package com.jy.appmarket.service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import cn.jpush.android.api.JPushInterface;
import cn.jpush.android.api.TagAliasCallback;

import com.jy.app.market.idata.card.CardUpgrade;
import com.jy.app.market.idata.data.Upgrade;
import com.jy.appmarket.network.engine.BaseNetEngine;
import com.jy.appmarket.network.engine.PushTagNetEngine;
import com.jy.appmarket.network.engine.UpgradeNetEngine;
import com.jy.appmarket.network.resultdata.PushTagResultData;
import com.jy.appmarket.network.resultdata.UpgradeResultData;
import com.jy.appmarket.network.task.NetTask;
import com.jy.appmarket.network.task.NetTask.NetTaskListener;
import com.jy.appmarket.notification.UpdateNotification;
import com.jy.appmarket.utils.LogUtil;
import com.jy.appmarket.utils.PackageUtils;
import com.jy.appmarket.utils.Prefs;

import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
import android.text.TextUtils;

public class UpdateService extends Service implements NetTaskListener {

	private static final String TAG = "UpdateService";
	public static final String ACTION_SHOW_UPGRADE_CARD = "com.jy.appmarket.action.SHOW_UPGRADE_CARD";
	public static final String ACTION_CHECK_DL_UPGRADE = "com.jy.appmarket.action.CHECK_DL_UPGRADE";
	public static final String EXTRA_UPGRADE_INFO = "upgrade_info";

	private static final long INTERVAL_MILLIS = 1000 * 60 * 60 * 3;

	private NetTask mNetTask;

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		LogUtil.i(TAG, "------>update startcommand");

		loadUpdateData();
		getPushTag();
		return super.onStartCommand(intent, flags, startId);
	}

	private void loadUpdateData() {
		UpgradeNetEngine engine = new UpgradeNetEngine();
		mNetTask = new NetTask(this, engine, 1);
		mNetTask.setListener(this);
		new Thread(mNetTask).start();
	}

	private void getPushTag() {
		PushTagNetEngine engine = new PushTagNetEngine();
		mNetTask = new NetTask(this, engine, 2);
		mNetTask.setListener(this);
		new Thread(mNetTask).start();
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		if (mNetTask != null) {
			mNetTask.cancel();
			mNetTask.setListener(null);
			mNetTask = null;
		}
	}

	@Override
	public void onTaskRunSuccessful(int tag, BaseNetEngine engine) {
		if (tag == 1) {
			UpgradeResultData resultData = (UpgradeResultData) engine.getResultData();
			if (resultData.isOK()) {
				int versionCode = PackageUtils.getVersionCode(this);
				CardUpgrade cardUpgrade = resultData.getCardUpgrade();
				if (cardUpgrade == null) {
					return;
				}
				Upgrade upgrade = cardUpgrade.getUpgrade();
				if (upgrade == null) {
					return;
				}
				if (versionCode != 0 && versionCode >= upgrade.getVersionCode()) {
					LogUtil.d(TAG, "update version code is low");
					return;
				}
				if (TextUtils.isEmpty(upgrade.getUrl())) {
					LogUtil.d(TAG, "download url is empty");
					return;
				}

				saveUpgradeInfo(upgrade);
				sendCheckDlUpgradeBroadcast(cardUpgrade);
				if (isTopApp()) {
					sendUpgradeBroadcast(cardUpgrade);
				} else {
					UpdateNotification.showUpdateNotification(this, false, upgrade);
				}
			}
		} else if (tag == 2) {
			PushTagResultData resultData = (PushTagResultData) engine.getResultData();
			if (resultData.isOK()) {
				List<String> tags = resultData.getmTags();
				Set<String> pushTag = new HashSet<String>();

				for (int i = 0; i < tags.size(); i++) {
					pushTag.add(tags.get(i));
				}
				setJpushTags(0, pushTag);
			}
		}
	}

	private void saveUpgradeInfo(Upgrade upgrade) {
		Prefs.saveUpgradeVersionCode(this, upgrade.getVersionCode());
		Prefs.saveUpgradeIcon(this, upgrade.getIcon());
		Prefs.saveUpgradeTitle(this, upgrade.getTitle());
		Prefs.saveUpgradeDetail(this, upgrade.getDetail());
		Prefs.saveUpgradeUrl(this, upgrade.getUrl());
		Prefs.saveUpgradeIndex(this, upgrade.getIndex());
	}

	@Override
	public void onTaskRunError(int tag) {
		// nothing todo
	}

	@Override
	public void onTaskRunCanceled(int tag) {
		// nothing todo
	}

	private boolean isTopApp() {
        return this.getPackageName().equals(PackageUtils.getTopAppPkg(this));
    }

	private void sendUpgradeBroadcast(CardUpgrade cardUpgrade) {
		Intent intent = new Intent();
		intent.setAction(ACTION_SHOW_UPGRADE_CARD);
		intent.putExtra(EXTRA_UPGRADE_INFO, cardUpgrade);
		sendBroadcast(intent);
	}

	private void sendCheckDlUpgradeBroadcast(CardUpgrade cardUpgrade) {
		Intent intent = new Intent();
		intent.setAction(ACTION_CHECK_DL_UPGRADE);
		intent.putExtra(EXTRA_UPGRADE_INFO, cardUpgrade);
		sendBroadcast(intent);
	}

	private void setJpushTags(final int retryCount, final Set<String> tags) {
		JPushInterface.setTags(getApplicationContext(), tags, new TagAliasCallback() {

			@Override
			public void gotResult(int responseCode, String alias, Set<String> tags) {

				if (responseCode == 6002) { // 超时
					if (retryCount < 3) {
						setJpushTags(retryCount + 1, tags);
					}
				}
			}
		});
	}

	public static void startUpdateService(Context context) {
		if (isServiceRunning(context)) {
			LogUtil.i(TAG, "update service is running!");
			return;
		}

		AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
		Intent intent = new Intent(context, UpdateService.class);
		PendingIntent pIntent = PendingIntent.getService(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
		am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), INTERVAL_MILLIS, pIntent);
	}

	public static boolean isServiceRunning(Context context) {
		boolean isRunning = false;
		ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		List<ActivityManager.RunningServiceInfo> serviceList = activityManager.getRunningServices(100);
		if (serviceList == null || serviceList.isEmpty()) {
			return false;
		}
		for (int i = 0; i < serviceList.size(); i++) {
			ComponentName cn = serviceList.get(i).service;
			if (UpdateService.class.getName().equals(cn.getClassName())
					&& context.getPackageName().equals(cn.getPackageName())) {
				isRunning = true;
				break;
			}
		}
		return isRunning;
	}

}
